﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BobcatUtility
{
    /// <summary>
    /// This class lets you log messages via static 'global' functions.
    /// It is observable via events to make it easy to show the logged data.
    /// </summary>
    public static class Logger
    {
        #region Public declarations

        public enum Level
        {
            DEBUG,
            NOTICE,
            WARN,
            ERROR,
            FATAL
        }

        #endregion

        #region Events

        /// <summary>
        /// Data passed with events raised by the Logger class.
        /// </summary>
        public class Args : EventArgs
        {
            public Level Level { get; set; }
            public string Message { get; set; }
        }

        /// <summary>
        /// Event raised when new messages are logged.
        /// </summary>
        public static event EventHandler<Args> MessageLoggedEvent;

        #endregion

        #region Public properties

        /// <summary>
        /// Gets or sets the logging level.
        /// </summary>
        public static Level LogLevel
        {
            get { return m_eLevel; }
            set { m_eLevel = value; }
        }

        #endregion

        #region Public methods

        /// <summary>
        /// Logs the message passed in at the level passed in.
        /// </summary>
        public static void log(string strMessage, Level eLevel)
        {
            log(strMessage, eLevel, 2);
        }

        /// <summary>
        /// Logs the message passed in at the level passed in. It also logs the
        /// name of the calling function which is the number of levels passed in
        /// back in the call stack.
        /// </summary>
        public static void log(string strMessage, Level eLevel, int iCallingFunctionLevel)
        {
            // We don't log unless the level is high enough...
            if (eLevel < m_eLevel)
            {
                return;
            }

            // We find the caller...
            string strCallingFunction = Utility.getCallingFunction(iCallingFunctionLevel);

            // We raise an event to any of our observers...
            Args args = new Args();
            args.Message = strMessage + " (" + strCallingFunction + ")";
            args.Level = eLevel;
            Utility.raiseEvent(MessageLoggedEvent, null, args);
        }

        #endregion

        #region Private data

        private static Level m_eLevel = Level.NOTICE;

        #endregion
    }
}
